package com.css.fxfzxczh.modules.hypergraph.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.css.fxfzxczh.base.dict.repository.DictItemRepository;
import com.css.fxfzxczh.base.dict.repository.entity.DictItemEntity;
import com.css.fxfzxczh.base.response.RestResponse;
import com.css.fxfzxczh.util.PlatformObjectUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Description: fxfzxczh
 * @Author: zyt
 * @CreateDate: 2023/8/7 10:23
 * 超图
 */
@Service
public class HypergraphService {

    @Value("${hypergraph.iServerHttp}")
    String iServerHttp;
    @Value("${hypergraph.userName}")
    String userName;
    @Value("${hypergraph.password}")
    String password;

//    @Resource
//    RestTemplate restTemplate;
    RestTemplate restTemplate = getRestTemplate();

    @Value("${hypergraph.filePath}")
    String filePath;
    @Value("${hypergraph.mapsPath}")
    String mapsPath;

    @Resource
    DictItemRepository dictItemRepository;

    /**
     * 调度器使用的RestTemplate，超时6000s
     * @return
     */
    public RestTemplate getRestTemplate(){
        RestTemplate restTemplate = new RestTemplateBuilder()
                .setConnectTimeout(Duration.ofSeconds(6000))
                .setReadTimeout(Duration.ofSeconds(6000))
                .build();
        //解决中文乱码
        List<HttpMessageConverter<?>> msgConv = restTemplate.getMessageConverters();
        if(msgConv != null && !msgConv.isEmpty()) {
            for(int i = 0; i < msgConv.size(); i++ ){
                if(msgConv.get(i).getClass().equals(StringHttpMessageConverter.class)) {
                    msgConv.set(i, new StringHttpMessageConverter(StandardCharsets.UTF_8));
                }
            }
        }
        return restTemplate;
    }

    /**
     * @param map layerName:
     *            type://类型
     *            WorkspaceReload//刷新指定超图工作空间数据源数据集
     *            exportShp//tif发布超图服务工具--创建任务（导出shp文件）
     * @return
     */
    public RestResponse getServerToken(Map<String, Object> map) {
        RestResponse restResponse = null;
        try {
            String dataUrl = iServerHttp + "/iserver/services/security/tokens.rjson";
            try {
                dataUrl = URLDecoder.decode(dataUrl, "utf-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
                return RestResponse.fail(e.getMessage());
            }
            dataUrl = dataUrl.replaceAll("%3A", ":").replaceAll("%2F", "/").replaceAll("\\+", "%20");
            //System.out.println(dataUrl);

            JSONObject jsonObject = new JSONObject();
            jsonObject.put("userName", userName);
            jsonObject.put("password", password);
            jsonObject.put("clientType", "NONE");//查询数量
            jsonObject.put("expiration", 600);//申请令牌的有效期，从发布令牌的时间开始计算，单位为分钟
            //System.out.println(jsonObject);

            HttpHeaders headers = new HttpHeaders();
            headers.set("Content-Type", "application/json; charset=UTF-8");

            HttpEntity<JSONObject> entity = new HttpEntity<>(jsonObject, headers);
            ResponseEntity<String> exchange = restTemplate.exchange(dataUrl, HttpMethod.POST, entity, String.class);

            // result.put("result", exchange.getBody());

            String type = (String) map.get("type");
            String layerName = (String) map.get("layerName");
            if (type.equals("exportShp")) {
                String sqlFilter = (String) map.get("sqlFilter");//过滤条件
                String timeStamp = (String) map.get("timeStamp");//时间戳，用于数据集导出名称后缀，防止重名
                String datasource = (String) map.get("datasource");//数据源fxfzxczh、datacenter
                //tif发布超图服务工具--创建任务（导出shp文件）
                restResponse = tifMapLayerToolJobPost(datasource, layerName, sqlFilter, timeStamp, exchange.getBody());
            } else if (type.equals("WorkspaceReload")) {
                String datasource = (String) map.get("datasource");//数据源
                String dataset = (String) map.get("dataset");//数据集
                //查询字典--超图数据源工作空间文件路径
                DictItemEntity dte = dictItemRepository.findOneByDictItemCodeAndDictId(datasource, "12");
                String smwuUrl = dte.getDictItemName();//工作空间文件路径
                //刷新指定超图工作空间数据源数据集
                restResponse = mapLayerWorkspaceReload(smwuUrl, datasource, dataset, exchange.getBody());
            } else if (type.equals("token")) {//获取超图服务token
                String token = exchange.getBody();
                restResponse = RestResponse.succeed(token);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return RestResponse.fail(e.getMessage());
        }
        return restResponse;
    }

    // tif发布超图服务工具--创建任务（导出shp文件）
    private RestResponse tifMapLayerToolJobPost(String datasource, String layerName,String sqlFilter,String timeStamp,String serverToken) {
        RestResponse restResponse = null;
        try {
            String dataUrl = iServerHttp + "/iserver/services/geoprocessing/restjsr/gp/v2/sps.WorkflowProcessFactory.models.tif发布:导出shp文件xczh/jobs?token=" + serverToken;
            if(datasource.equals("fxfzxczh")){
                dataUrl = iServerHttp + "/iserver/services/geoprocessing/restjsr/gp/v2/sps.WorkflowProcessFactory.models.tif发布:导出shp文件xczh/jobs?token=" + serverToken;
            }else if(datasource.equals("datacenter")){
                dataUrl = iServerHttp + "/iserver/services/geoprocessing/restjsr/gp/v2/sps.WorkflowProcessFactory.models.tif发布:导出shp文件基础数据/jobs?token=" + serverToken;
            }
            if(layerName.equals("xzch_fast_seismic_influence") || layerName.equals("xzch_draw_seismic_influence")){
                dataUrl = iServerHttp + "/iserver/services/geoprocessing/restjsr/gp/v2/sps.WorkflowProcessFactory.models.tif发布:导出shp文件影响场xczh/jobs?token=" + serverToken;
            }
            try {
                dataUrl = URLDecoder.decode(dataUrl, "utf-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
                return RestResponse.fail(e.getMessage());
            }
            dataUrl = dataUrl.replaceAll("%3A", ":").replaceAll("%2F", "/").replaceAll("\\+", "%20");
            //System.out.println(dataUrl);
            String resultFilePath = filePath + layerName + "_" + timeStamp + ".file";//导出文件路径
            //过滤条件
            String sql = "1=1";
            if (!PlatformObjectUtils.isEmpty(sqlFilter)) {
                sql = sqlFilter;
            }
            //执行处理自动化工具时的参数设置，形式为{”ParameterID1”:”value1”,”ParameterID2”:”value2”,……}，其中ParameterID为工具的参数ID，由对应的处理自动化工具描述可以确定，value为参数的值
            JSONObject jsonObject = new JSONObject();
            JSONObject parameter = new JSONObject();
            parameter.put("String_1", layerName);//数据集名称（表名）
            parameter.put("String_2", resultFilePath);//导出文件路径
            parameter.put("String_3", sql);//过滤条件
            if(layerName.equals("xzch_fast_seismic_influence")){
                parameter.put("String", "fsi_id");//忽略字段名
            }else if(layerName.equals("xzch_draw_seismic_influence")){
                parameter.put("String", "si_id");//忽略字段名
            }
            jsonObject.put("parameter", parameter);
            JSONArray environment = new JSONArray();
            jsonObject.put("environment", environment);

            HttpHeaders headers = new HttpHeaders();
            headers.set("Content-Type", "application/json; charset=UTF-8");

            HttpEntity<JSONObject> entity = new HttpEntity<>(jsonObject, headers);
            ResponseEntity<JSONObject> exchange = restTemplate.exchange(dataUrl, HttpMethod.POST, entity, JSONObject.class);
            JSONObject body = exchange.getBody();
            if (body == null) {
                return RestResponse.fail("未获取到数据！");
            }
            // result.put("result", body.getString("jobID"));

            restResponse = tifMapLayerToolJobGet(body.getString("jobID"), serverToken);
            if (restResponse.getCode() == 200) {
                JSONObject jsonObject1 = new JSONObject();
                jsonObject1.put("dataset", layerName);
                jsonObject1.put("resultFilePath", resultFilePath);
                restResponse.setData(jsonObject1);
            }

        } catch (Exception e) {
            e.printStackTrace();
            return RestResponse.fail(e.getMessage());
        }
        return restResponse;
    }

    private RestResponse tifMapLayerToolJobGet(String jobID, String serverToken) {
        JSONObject result = new JSONObject();
        try {
            String dataUrl = iServerHttp + "/iserver/services/geoprocessing/restjsr/gp/v2/jobs/" + jobID + ".json?token=" + serverToken;
            try {
                dataUrl = URLDecoder.decode(dataUrl, "utf-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
                return RestResponse.fail(e.getMessage());
            }
            dataUrl = dataUrl.replaceAll("%3A", ":").replaceAll("%2F", "/").replaceAll("\\+", "%20");
            //System.out.println(dataUrl);

            HttpHeaders headers = new HttpHeaders();
            headers.set("Content-Type", "application/json; charset=UTF-8");

            HttpEntity<JSONObject> entity = new HttpEntity<>(new JSONObject(), headers);
            ResponseEntity<JSONObject> exchange = restTemplate.exchange(dataUrl, HttpMethod.GET, entity, JSONObject.class);
            JSONObject body = exchange.getBody();
            if (body == null) {
                return RestResponse.fail("未获取到数据！");
            }
            if (!body.getJSONObject("state").getBooleanValue("success")
                    && !body.getJSONObject("state").getString("runState").equals("RUNNING")) {
                return RestResponse.fail("未获取到数据！");
            }
            BigDecimal percent = body.getJSONObject("progress").getBigDecimal("percent");
            while (percent.compareTo(BigDecimal.valueOf(100)) < 0) {
                Thread.sleep(500);
                //获取任务执行百分比
                percent = tifMapLayerToolJobGetPercent(jobID, serverToken);
                if (percent.compareTo(BigDecimal.valueOf(-1)) == 0) {
                    return RestResponse.fail("该任务未获取到数据！");
                }
            }
            result.put("result", "获取成功！");
        } catch (Exception e) {
            e.printStackTrace();
            if(e.getMessage().contains("无效的令牌")){
                return RestResponse.fail("无效的令牌！");
            }
            tifMapLayerToolJobGet(jobID, serverToken);
        }
        return RestResponse.succeed(result);
    }

    //获取任务执行百分比
    private BigDecimal tifMapLayerToolJobGetPercent(String jobID, String serverToken) {
        BigDecimal jobPercent = BigDecimal.ZERO;
        try {
            String dataUrl = iServerHttp + "/iserver/services/geoprocessing/restjsr/gp/v2/jobs/" + jobID + ".json?token=" + serverToken;
            try {
                dataUrl = URLDecoder.decode(dataUrl, "utf-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
                return jobPercent;
            }
            dataUrl = dataUrl.replaceAll("%3A", ":").replaceAll("%2F", "/").replaceAll("\\+", "%20");
            //System.out.println(dataUrl);

            HttpHeaders headers = new HttpHeaders();
            headers.set("Content-Type", "application/json; charset=UTF-8");

            HttpEntity<JSONObject> entity = new HttpEntity<>(new JSONObject(), headers);
            ResponseEntity<JSONObject> exchange = restTemplate.exchange(dataUrl, HttpMethod.GET, entity, JSONObject.class);
            JSONObject body = exchange.getBody();
            if (body == null) {
                return jobPercent;
            }
            if (!body.getJSONObject("state").getBooleanValue("success")
                    && !body.getJSONObject("state").getString("runState").equals("RUNNING")) {
                return BigDecimal.valueOf(-1);
            }
            BigDecimal percent = body.getJSONObject("progress").getBigDecimal("percent");
            if(percent.compareTo(BigDecimal.valueOf(100)) == 0){
                if(body.getJSONObject("state").getString("runState").equals("RUNNING")){//正在执行
                    percent = BigDecimal.valueOf(99);
                }
            }
            jobPercent = percent;
        } catch (Exception e) {
            e.printStackTrace();
            if(e.getMessage().contains("无效的令牌")){
                return BigDecimal.valueOf(-1);
            }
            return jobPercent;
        }
        return jobPercent;
    }

    //刷新指定超图工作空间数据源数据集
    private RestResponse mapLayerWorkspaceReload(String smwuUrl, String datasource, String dataset, String serverToken) {
        RestResponse restResponse = null;
        try {
            String dataUrl = iServerHttp + "/iserver/manager/workspaces/workspacereload.rjson?token=" + serverToken;
            try {
                dataUrl = URLDecoder.decode(dataUrl, "utf-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
                return RestResponse.fail(e.getMessage());
            }
            dataUrl = dataUrl.replaceAll("%3A", ":").replaceAll("%2F", "/").replaceAll("\\+", "%20");
            //刷新指定数据源数据集时的参数设置，形式为{"workspaceConnectionInfo":"E:/MapData/fxfzdzzh/fxfzdzzh10/fxfzdzzh.smwu","isForce":true,"datasets":{"fxfzdzzh":["dzzh_slide_result_intensity"]}}
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("workspaceConnectionInfo", smwuUrl);
            jsonObject.put("isForce", true);
            //有数据集名则刷新指定数据集，无数据集名则刷新整个数据源
            if (PlatformObjectUtils.isNotEmpty(dataset)) {
                JSONObject datasets = new JSONObject();
                JSONArray datasetArray = new JSONArray();
                datasetArray.add(dataset);
                datasets.put(datasource, datasetArray);//数据源数据集名称
                jsonObject.put("datasets", datasets);
            }

            HttpHeaders headers = new HttpHeaders();
            headers.set("Content-Type", "application/json; charset=UTF-8");

            HttpEntity<JSONObject> entity = new HttpEntity<>(jsonObject, headers);
            ResponseEntity<String> exchange1 = restTemplate.exchange(dataUrl, HttpMethod.POST, entity, String.class);
//            ResponseEntity<JSONObject> exchange = restTemplate.exchange(dataUrl, HttpMethod.POST, entity, JSONObject.class);
            JSONObject body = JSON.parseObject(exchange1.getBody());
            if (body == null) {
                return RestResponse.fail("未获取到数据！");
            }
            if (body.getBooleanValue("succeed")) {
                restResponse = RestResponse.succeed("刷新成功");
            } else {
                restResponse = RestResponse.fail("刷新失败");
            }

        } catch (Exception e) {
            e.printStackTrace();
            return RestResponse.fail(e.getMessage());
        }
        return restResponse;
    }

    //刷新指定超图工作空间数据源数据集
    public boolean getWorkspaceReload(String dataset) {
        boolean bool = false;
        Map<String, Object> map = new HashMap<>();
        map.put("type", "WorkspaceReload");
        map.put("datasource", "fxfzxczh");//数据源（数据库名）
        map.put("dataset", dataset);//数据集（表名）
        RestResponse restResponse1 = getServerToken(map);//刷新指定超图工作空间数据源数据集
        if (restResponse1.getCode() == 200) {
            //刷新成功
            bool = true;
        }

        return bool;
    }

    //获取超图服务token
    public String getToken() {
        Map<String, Object> map = new HashMap<>();
        map.put("type", "token");
        RestResponse restResponse = getServerToken(map);
        String token = (String) restResponse.getData();

        return token;
    }

    //导出shp文件
    public String exportShpFile(String datasource,String dataset,String sqlFilter,String timeStamp) {
        String resultFilePath = "";
        Map<String, Object> map = new HashMap<>();
        map.put("type", "exportShp");
        map.put("layerName", dataset);//数据集（表名）
        map.put("sqlFilter", sqlFilter);//过滤条件
        map.put("timeStamp", timeStamp);//时间戳，用于数据集名称后缀，防止重名
        map.put("datasource", datasource);//数据源fxfzxczh、datacenter
        RestResponse restResponse1 = getServerToken(map);//导出shp文件
        if (restResponse1.getCode() == 200) {
            //导出成功
            JSONObject json = (JSONObject) JSON.toJSON(restResponse1.getData());
            resultFilePath = (String)json.get("resultFilePath");
        }

        return resultFilePath;
    }
}
